home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
tcp_ip
/
os2
/
pmnos11s
/
dirutil.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-30
|
13KB
|
599 lines
/* dirutil.c - MS-DOS directory reading routines
*
* Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
* Directory sorting by Mike Chepponis, K3MC
* New version using regs.h by Russell Nelson.
* Rewritten for Turbo-C 2.0 routines by Phil Karn, KA9Q 25 March 89
*/
#if defined(OS2)
#define INCL_DOSFILEMGR
#include <os2.h>
#include <stdio.h>
#include <direct.h>
#else
#include <dir.h>
#include <dos.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "config.h"
#include "global.h"
#include "proc.h"
#include "session.h"
#include "dirutil.h"
#include "commands.h"
#ifdef CALLSERVER
#include <string.h>
#include <alloc.h>
extern char *CDROM; /* buckbook.c: defines CDROM drive letter e.g. "s:" */
#endif
struct dirsort {
struct dirsort *next;
FILEFINDBUF3 de;
};
#define NULLSORT (struct dirsort *)0
#if defined(OS2)
static FILEFINDBUF3 sbuf;
static unsigned short usSearchCount = 1;
static HDIR hDir = HDIR_CREATE;
#endif
static void commas __ARGS((char *dest));
static int fncmp __ARGS((char *a, char *b));
static void format_fname_full __ARGS((FILE *file,FILEFINDBUF3 *sbuf,int full,
int n));
static void free_clist __ARGS((struct dirsort *this));
#ifdef notdef
static int getdir_nosort __ARGS((char *path,int full,FILE *file));
#endif
static int nextname __ARGS((int command, char *name, FILEFINDBUF3 *sbuf));
static void print_free_space __ARGS((FILE *file,int n));
static void undosify __ARGS((char *s));
static char *wildcardize __ARGS((char *path));
#if defined(OS2)
int findfirst(char *, FILEFINDBUF3 *, int);
int findnext(FILEFINDBUF3 *);
#endif
#define REGFILE (FA_HIDDEN|FA_SYSTEM|FA_DIREC)
#define insert_ptr(list,new) (new->next = list,list = new)
#if defined(OS2)
int findfirst(char *pszName, FILEFINDBUF3 *pBuffer, int usAttrib)
{
ULONG rc;
ULONG ulSearchCount = 1;
rc = DosFindFirst(pszName,
&hDir,
usAttrib,
pBuffer,
sizeof(FILEFINDBUF3),
&ulSearchCount,
FIL_STANDARD);
rc = (rc == 0 ? 1 : 0);
return(rc);
}
int findnext(FILEFINDBUF3 *pBuffer)
{
ULONG rc;
ULONG usSearchCount = 1;
rc = DosFindNext(hDir,
pBuffer,
sizeof(FILEFINDBUF3),
&usSearchCount);
rc = (rc == 0 ? 1 : 0);
if (rc == 0)
DosFindClose(hDir);
return(rc);
}
#endif
/* Create a directory listing in a temp file and return the resulting file
* descriptor. If full == 1, give a full listing; else return just a list
* of names.
*/
FILE *
dir(path,full)
char *path;
int full;
{
FILE *fp;
if((fp = tmpfile()) != NULLFILE){
getdir(path,full,fp);
rewind(fp);
}
return fp;
}
/* find the first or next file and lowercase it. */
static int
nextname(command, name, sbuf)
int command;
char *name;
#if defined(OS2)
FILEFINDBUF3 *sbuf;
#else
struct ffblk *sbuf;
#endif
{
int found;
switch(command){
case 0:
#if defined(OS2)
hDir = HDIR_CREATE;
found = findfirst(name,sbuf,FILE_NORMAL | FILE_DIRECTORY);
#else
found = findfirst(name,sbuf,REGFILE);
#endif
break;
default:
found = findnext(sbuf);
}
found = (found == 1) ? 1 : -1;
if(found == 1)
strlwr(sbuf->achName);
return found;
}
/* wildcard filename lookup */
int
filedir(name,times,ret_str)
char *name;
int times;
char *ret_str;
{
int rval;
switch(times){
case 0:
#if defined(OS2)
hDir = HDIR_CREATE;
rval = findfirst(name,&sbuf,FILE_NORMAL);
#else
rval = findfirst(name,&sbuf,REGFILE);
#endif
break;
default:
rval = findnext(&sbuf);
break;
}
if(rval == 0){
ret_str[0] = '\0';
} else {
/* Copy result to output */
strcpy(ret_str, sbuf.achName);
}
return rval;
}
/* do a directory list to the stream
* full = 0 -> short form, 1 is long
*/
int
getdir(path,full,file)
char *path;
int full;
FILE *file;
{
FILEFINDBUF3 sbuf;
int command = 0;
int n = 0;
struct dirsort *head, *here, *new;
path = wildcardize(path);
head = NULLSORT; /* No head of chain yet... */
for(;;){
if (nextname(command, path, &sbuf) == -1)
break;
command = 1; /* Got first one already... */
#if defined(OS2)
if (sbuf.achName[0] == '.') /* drop "." and ".." */
continue;
#endif
new = (struct dirsort *) mallocw(sizeof(struct dirsort));
new->de = sbuf; /* Copy contents of directory entry struct */
/* insert it into the list */
if (!head || fncmp(new->de.achName, head->de.achName) < 0) {
insert_ptr(head, new);
} else {
register struct dirsort *this;
for (this = head;
this->next != NULLSORT;
this = this->next)
if (fncmp(new->de.achName, this->next->de.achName) < 0)
break;
insert_ptr(this->next, new);
}
} /* infinite FOR loop */
for (here = head; here; here = here->next)
format_fname_full(file,&here->de,full,++n);
/* Give back all the memory we temporarily needed... */
free_clist(head);
if(full)
print_free_space(file, n);
return 0;
}
static int
fncmp(a,b)
register char *a, *b;
{
int i;
for(;;){
if (*a == '.')
return -1;
if (*b == '.')
return 1;
if ((i = *a - *b++) != 0)
return i;
if (!*a++)
return -1;
}
}
#if defined(ALLCMD)
/* Change working directory */
int
docd(argc,argv,p)
int argc;
char *argv[];
void *p;
{
char *dirname;
ULONG ulDirSize = 256;
dirname = (char *)mallocw(256);
if(argc > 1){
#if !defined(OS2)
if(chdir(argv[1]) == -1){
#else
if (DosSetCurrentDir(argv[1]) != 0) {
#endif
tprintf("Can't change directory\n");
return 1;
}
}
#if !defined(OS2)
if(getcwd(dirname,256) != NULLCHAR){
#else
if(!DosQCurDir(0, dirname, &ulDirSize)){
#endif
undosify(dirname);
tprintf("%s\n",dirname);
}
return 0;
free(dirname);
}
/* List directory to console */
int
dodir(argc,argv,p)
int argc;
char *argv[];
void *p;
{
char *path;
FILE *fp;
char tmpname[80];
char **margv;
/*Make sure this comes from console - WG7J*/
if(Curproc->input != Command->input)
return 0;
if(argc >= 2)
path = argv[1];
else
path = "*.*";
margv = (char **)callocw(2,sizeof(char *));
tmpnam(tmpname);
fp = fopen(tmpname,WRITE_TEXT);
getdir(path,1,fp);
fclose(fp);
margv[1] = strdup(tmpname);
domore(2,margv,p);
remove(tmpname);
return 0;
}
/* Create directory */
int
domkd(argc,argv,p)
int argc;
char *argv[];
void *p;
{
#if !defined(OS2)
if(mkdir(argv[1]) == -1)
#else
if (DosCreateDir(argv[1], 0) != 0)
#endif
tprintf("Can't make %s: %s\n",argv[1],strerror(errno));
return 0;
}
/* Remove directory */
int
dormd(argc,argv,p)
int argc;
char *argv[];
void *p;
{
#if !defined(OS2)
if(rmdir(argv[1]) == -1)
#else
if(DosDeleteDir(argv[1]) != 0)
#endif
tprintf("Can't remove %s: %s\n",argv[1],strerror(errno));
return 0;
}
#endif /*ALLCMD*/
/*
* Return a string with commas every 3 positions.
* the original string is replace with the string with commas.
*
* The caller must be sure that there is enough room for the resultant
* string.
*
*
* k3mc 4 Dec 87
*/
static void
commas(dest)
char *dest;
{
char *src, *core; /* Place holder for malloc */
unsigned cc; /* The comma counter */
unsigned len;
len = strlen(dest);
/* Make a copy, so we can muck around */
core = src = strdup(dest);
cc = (len-1)%3 + 1; /* Tells us when to insert a comma */
while(*src != '\0'){
*dest++ = *src++;
if( ((--cc) == 0) && *src ){
*dest++ = ','; cc = 3;
}
}
free(core);
*dest = '\0';
}
/* fix up the filename so that it contains the proper wildcard set */
static char *
wildcardize(PCHAR path)
{
#if defined(OS2)
FILEFINDBUF3 sbuf;
static char ourpath[255];
#else
struct ffblk sbuf;
static char ourpath[[64];
#endif
if (strchr(path, '*'))
return(path); /* already asking for wildcard */
/* Root directory is a special case */
if(path == NULLCHAR ||
*path == '\0' ||
strcmp(path,"\\") == 0 ||
strcmp(path,"/") == 0)
path = "\\*.*";
#ifdef CALLSERVER
if (CDROM != NULLCHAR && strcmp(path, CDROM) == 0) {
path = (char *) mallocw(7); /* THIS causes a memory leak ! - WG7J */
sprintf(path, "%s/*.*", CDROM);
}
#endif
/* if they gave the name of a subdirectory, append \*.* to it */
#if defined(OS2)
if ((nextname(0, path, &sbuf) == 1) &&
(sbuf.attrFile & FILE_DIRECTORY)) {
DosFindClose(hDir);
/* if there isn't enough room, give up -- it's invalid anyway */
if (strlen(path) + 4 > 254) return path;
#else
if (nextname(0, path, &sbuf) &&
(sbuf.ff_attrib & FA_DIREC) &&
!nextname(1, path, &sbuf)) {
/* if there isn't enough room, give up -- it's invalid anyway */
if (strlen(path) + 4 > 63) return path;
#endif
strcpy(ourpath, path);
strcat(ourpath, "\\*.*");
return ourpath;
}
#if defined(OS2)
if (hDir != HDIR_CREATE)
DosFindClose(hDir);
#endif
return path;
}
static void
format_fname_full(file, sbuf, full, n)
FILE *file;
#if defined(OS2)
FILEFINDBUF3 *sbuf;
#else
struct ffblk *sbuf;
#endif
int full, n;
{
char line_buf[50]; /* for long dirlist */
char cbuf[20]; /* for making line_buf */
#if defined(OS2)
strcpy(cbuf,sbuf->achName);
if(sbuf->attrFile & FILE_DIRECTORY) strcat(cbuf, "/");
#else
strcpy(cbuf,sbuf->ff_name);
if(sbuf->ff_attrib & FA_DIREC) strcat(cbuf, "/");
#endif
if (full) {
/* Long form, give other info too */
sprintf(line_buf,"%-13s",cbuf);
#if defined(OS2)
if(sbuf->attrFile & FILE_DIRECTORY)
#else
if(sbuf->ff_attrib & FA_DIREC)
#endif
strcat(line_buf," ");/* 11 spaces */
else {
sprintf(cbuf,"%ld",sbuf->cbFile);
commas(cbuf);
sprintf(line_buf+strlen(line_buf),"%10s ",cbuf);
}
sprintf(line_buf+strlen(line_buf),"%2d:%02d %2d/%02d/%02d%s",
#if defined(OS2)
sbuf->ftimeLastWrite.hours, /* hour */
sbuf->ftimeLastWrite.minutes, /* minute */
sbuf->fdateLastWrite.month, /* month */
sbuf->fdateLastWrite.day, /* day */
sbuf->fdateLastWrite.year + 80, /* year */
#else
(sbuf->ff_ftime >> 11) & 0x1f, /* hour */
(sbuf->ff_ftime >> 5) & 0x3f, /* minute */
(sbuf->ff_fdate >> 5) & 0xf, /* month */
(sbuf->ff_fdate ) & 0x1f, /* day */
(sbuf->ff_fdate >> 9) + 80, /* year */
#endif
(n & 1) ? " " : "\n");
fputs(line_buf,file);
} else {
fputs(cbuf,file);
fputs("\n",file);
}
}
/* Provide additional information only on DIR */
static void
print_free_space(file, n)
FILE *file;
int n;
{
unsigned long free_bytes, total_bytes;
char s_free[11], s_total[11];
char cbuf[20];
#if defined(OS2)
FSALLOCATE dtable;
unsigned long bpcl, ulLogical;
unsigned long ulDrive;
if(n & 1)
fputs("\n",file);
/* Find disk free space */
/*getdfree(0,&dtable);*/
DosQCurDisk(&ulDrive, &ulLogical);
DosQFSInfo(ulDrive, 1, (char *)&dtable, sizeof(dtable));
bpcl = dtable.cSectorUnit * dtable.cbSector;
free_bytes = dtable.cUnitAvail * bpcl;
total_bytes = dtable.cUnit * bpcl;
#else
struct dfree dtable;
unsigned long bpcl;
char resolved[80]; /* may need as little as 67 */
union REGS regs;
struct SREGS sregs;
int drive;
/* do an undocumented call to find wich drive this mane resolves to */
regs.x.si = FP_OFF(path);
sregs.ds = FP_SEG(path);
regs.x.di = FP_OFF(resolved);
sregs.es = FP_SEG(resolved);
regs.h.ah = 0x60;
intdosx(®s,®s,&sregs);
drive = resolved[0] - '@';
if(n & 1)
fputs("\n",file);
/* Find disk free space */
getdfree(drive,&dtable);
bpcl = dtable.df_bsec * dtable.df_sclus;
free_bytes = dtable.df_avail * bpcl;
total_bytes = dtable.df_total * bpcl;
#endif
sprintf(s_free,"%ld",free_bytes);
commas(s_free);
sprintf(s_total,"%ld",total_bytes);
commas(s_total);
if(n)
sprintf(cbuf,"%d",n);
else
strcpy(cbuf,"No");
fprintf(file,"%s file%s. %s bytes free. Disk size %s bytes.\n",
cbuf,(n==1? "":"s"),s_free,s_total);
}
static void
free_clist(this)
struct dirsort *this;
{
struct dirsort *next;
while (this != NULLSORT) {
next = this->next;
free(this);
this = next;
}
}
#ifdef notdef
static int
getdir_nosort(path,full,file)
char *path;
int full;
FILE *file;
{
FILEFINDBUF3 sbuf;
int command;
int n = 0; /* Number of directory entries */
path = wildcardize(path);
command = 0;
while(nextname(command, path, &sbuf)){
command = 1; /* Got first one already... */
#if defined(OS2)
if (sbuf.achName[0] == '.') /* drop "." and ".." */
#else
if (sbuf.ff_name[0] == '.') /* drop "." and ".." */
#endif
continue;
format_fname_full(file, &sbuf, full, ++n);
}
if(full)
print_free_space(file, n);
return 0;
}
#endif
/* Translate those %$#@!! backslashes to proper form */
static void
undosify(s)
char *s;
{
while(*s != '\0'){
if(*s == '\\')
*s = '/';
s++;
}
}